#include "Conteo.h"
#include "Utils.h"
#include <sstream>

using namespace Entidades;

Conteo::Conteo() {
	this->lista = new Lista();
	this->distrito = new Distrito();
	this->eleccion = new Eleccion();
}

Distrito *Conteo::getDistrito() const {
	return distrito;
}

Eleccion *Conteo::getEleccion() const {
	return eleccion;
}

Lista *Conteo::getLista() const {
	return lista;
}

unsigned int Conteo::getCantidadDeVotos() const {
	return this->cantidadDeVotos;
}

void Conteo::setDistrito(string nombreDeDistrito) {
	this->distrito->setNombre(nombreDeDistrito);
}

void Conteo::setEleccion(int fecha, string cargo) {
	this->eleccion->setFecha(fecha);
	this->eleccion->setCargo(cargo);
	this->lista->getEleccion()->setFecha(fecha);
	this->lista->getEleccion()->setCargo(cargo);
}

void Conteo::setLista(string nombreLista) {
	this->lista->setNombre(nombreLista);
}

void Conteo::sumarUnVoto() {
	this->cantidadDeVotos = this->cantidadDeVotos + 1;
}

void Conteo::setCantidadDeVotos(unsigned int cantidadDeVotos) {
	this->cantidadDeVotos = cantidadDeVotos;
}

void Conteo::hidratarse(char* buffer, unsigned int tamanioDelBuffer) {
	//escribo el buffer en el stringStream
	stringstream* ss = new stringstream(stringstream::in | stringstream::out | stringstream::binary);
	ss->seekg(0, ios::beg);
	ss->write(buffer, tamanioDelBuffer);

	//Eleccion (fecha int, Cargo -string cargoPrincipal-)
	unsigned int fechaDeEleccion;
	ss->read((char*) &(fechaDeEleccion), sizeof(int));
	this->eleccion->setFecha(fechaDeEleccion);
	this->eleccion->setCargo(Utils::ObtenerSiguienteStringVariable(ss));

	//Distrito (string: nombre)
	this->distrito->setNombre(Utils::ObtenerSiguienteStringVariable(ss));

	//Lista (eleccion - nombre string)
	this->lista->setNombre(Utils::ObtenerSiguienteStringVariable(ss));
	this->lista->setEleccion(eleccion->getFecha(), eleccion->getCargo()->getNombre());

	//cantidadDeVotos int
	ss->read((char*) &(this->cantidadDeVotos), sizeof(int));

	delete ss;
}

char* Conteo::construirBuffer() {
	//guardo fecha int | cargo string | distrito string | nombreLista string | cantidadDeVotos

	//agrupo los atributos
	stringstream* ss = new stringstream(stringstream::in | stringstream::out | stringstream::binary);
	ss->seekp(0, ios::end);

	//Eleccion (fecha int, Cargo -string cargoPrincipal-)
	unsigned int fecha = this->eleccion->getFecha();
	ss->write((char*) &(fecha), sizeof(int));
	unsigned int tamanioDelCargo = this->eleccion->getCargo()->getNombre().size();
	ss->write((char*) &tamanioDelCargo, sizeof(int));
	ss->write(this->eleccion->getCargo()->getNombre().c_str(), tamanioDelCargo);

	//Distrito (string nombre)
	unsigned int tamanioDelNombreDeDistrito = this->distrito->getNombre().size();
	ss->write((char*) &tamanioDelNombreDeDistrito, sizeof(int));
	ss->write(this->distrito->getNombre().c_str(), tamanioDelNombreDeDistrito);

	//Lista (eleccion - nombre string)
	unsigned int tamanioDelNombreDeLaLista = this->lista->getNombre().size();
	ss->write((char*) &tamanioDelNombreDeLaLista, sizeof(int));
	ss->write(this->lista->getNombre().c_str(), tamanioDelNombreDeLaLista);

	//CantidadDeVotos
	ss->write((char*) &(this->cantidadDeVotos), sizeof(int));

	//construyo el buffer
	unsigned int tamanioDelBuffer = this->getTamanioDelBuffer();
	char* buffer = new char[tamanioDelBuffer];
	ss->read(buffer, tamanioDelBuffer);
	delete ss;

	//lo devuelvo
	return buffer;
}

unsigned int Conteo::getTamanioDelBuffer() {
	return (5 * sizeof(int))+ eleccion->getCargo()->getNombre().size() + distrito->getNombre().size()
			+ lista->getNombre().size();
}

void Conteo::marcarComoBorrado() {

}

Conteo::~Conteo() {
	delete lista;
	delete distrito;
	delete eleccion;
}
